<template>
  <div class="bpmn-editor-container">
    <!-- 工具栏 -->
    <div class="toolbar">
      <el-button @click="importDiagram">导入XML</el-button>
      <el-button @click="exportDiagram">导出XML</el-button>
      <el-button @click="saveDiagram">保存</el-button>
      <input
        ref="fileInput"
        type="file"
        style="display: none"
        accept=".bpmn"
        @change="onFileSelected"
      />
    </div>

    <!-- BPMN画布 -->
    <div ref="canvas" class="canvas"></div>

    <!-- 自定义属性面板 -->
    <div v-if="selectedElement" class="properties-panel">
      <h3>属性编辑</h3>
      <el-form ref="propertyForm" :model="elementProperties" label-width="100px">
        <el-form-item label="ID">
          <el-input v-model="elementProperties.id" disabled></el-input>
        </el-form-item>
        <el-form-item label="名称">
          <el-input
            v-model="elementProperties.name"
            @input="updateProperty('name', elementProperties.name)"
          ></el-input>
        </el-form-item>
        <el-form-item v-if="isUserTask" label="审批人">
          <el-input
            v-model="elementProperties.assignee"
            @input="updateProperty('assignee', elementProperties.assignee)"
          ></el-input>
        </el-form-item>
        <el-form-item v-if="isUserTask" label="候选人">
          <el-input
            v-model="elementProperties.candidateUsers"
            @input="updateProperty('candidateUsers', elementProperties.candidateUsers)"
          ></el-input>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script setup lang="ts">
import BpmnModeler from "bpmn-js/lib/Modeler";
import { Element } from "diagram-js/lib/model/Element";
import "bpmn-js/dist/assets/diagram-js.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
import customTranslate from "@/utils/bpmn/customTranslate/customTranslate";
import CustomPaletteProvider from "@/utils/bpmn/ customPaletteProvider/CustomPaletteProvider"; // 自定义左侧工具栏

// 画布和模型器实例
const canvas = ref<HTMLDivElement | null>(null);
const fileInput = ref<HTMLInputElement | null>(null);
const modeler = ref<BpmnModeler | null>(null);
const selectedElement = ref<Element | null>(null);
const elementProperties = reactive<{
  id: string;
  name: string;
  assignee?: string;
  candidateUsers?: string;
}>({
  id: "",
  name: "",
  assignee: "",
  candidateUsers: "",
});

// 默认BPMN XML
const DEFAULT_XML = `<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
  xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
  xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd"
  id="Definitions_1"
  targetNamespace="http://bpmn.io/schema/bpmn">
  <bpmn:process id="Process_1" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1" name="开始" />
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="173" y="102" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="182" y="145" width="19" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>`;

// 初始化模型器
onMounted(async () => {
  if (!canvas.value) return;

  // 创建模型器实例
  modeler.value = new BpmnModeler({
    container: canvas.value,
    additionalModules: [
      { translate: ["value", customTranslate] }, // 汉化
      { paletteProvider: ["type", CustomPaletteProvider] },
    ],
  });

  // 加载默认XML
  await loadXml(DEFAULT_XML);

  // 监听元素选择事件
  const eventBus = modeler.value.get("eventBus");
  eventBus.on("element.click", (event: { element: Element }) => {
    selectElement(event.element);
  });
});

// 加载XML
async function loadXml(xml: string) {
  if (!modeler.value) return;

  try {
    const result = await modeler.value.importXML(xml);
    const { warnings } = result;
    console.log("Warnings during import:", warnings);
  } catch (err) {
    console.error("Error importing BPMN XML:", err);
  }
}

// 选择元素
function selectElement(element: Element) {
  selectedElement.value = element;

  // 提取元素属性
  elementProperties.id = element.id || "";
  elementProperties.name = element.businessObject.name || "";

  // 处理用户任务特有属性
  if (element.type === "bpmn:UserTask") {
    const bo = element.businessObject;
    elementProperties.assignee = bo.assignee || "";
    elementProperties.candidateUsers = bo.candidateUsers || "";
  } else {
    elementProperties.assignee = "";
    elementProperties.candidateUsers = "";
  }
}

// 更新属性
function updateProperty(property: string, value: string) {
  if (!modeler.value || !selectedElement.value) return;

  const modeling = modeler.value.get("modeling");
  //selectedElement.value.businessObject;
  // 更新属性
  modeling.updateProperties(selectedElement.value, {
    [property]: value,
  });
}

// 导入XML
function importDiagram() {
  fileInput.value?.click();
}

// 文件选择处理
async function onFileSelected(event: Event) {
  const target = event.target as HTMLInputElement;
  if (!target.files || target.files.length === 0) return;

  const file = target.files[0];
  const reader = new FileReader();

  reader.onload = async (e) => {
    const xml = e.target?.result as string;
    await loadXml(xml);
  };

  reader.readAsText(file);
  target.value = "";
}

// 导出XML
async function exportDiagram() {
  if (!modeler.value) return;

  try {
    const result = await modeler.value.exportXML({
      format: true,
    });
    const { xml } = result;

    // 创建下载链接
    const blob = new Blob([xml], { type: "application/xml" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "diagram.bpmn";
    a.click();
    URL.revokeObjectURL(url);
  } catch (err) {
    console.error("Error exporting BPMN XML:", err);
  }
}

// 保存当前图
async function saveDiagram() {
  if (!modeler.value) return;

  try {
    const result = await modeler.value.exportXML({
      format: true,
    });
    const { xml } = result;

    // 这里可以发送到后端保存
    console.log("BPMN XML to save:", xml);
    // 示例: await saveToBackend(xml);
    alert("流程图已保存");
  } catch (err) {
    console.error("Error saving BPMN XML:", err);
  }
}

// 判断是否为用户任务
const isUserTask = computed(() => {
  return selectedElement.value?.type === "bpmn:UserTask";
});
</script>

<style scoped>
.bpmn-editor-container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.toolbar {
  display: flex;
  gap: 10px;
  padding: 10px;
  background-color: #f5f5f5;
  border-bottom: 1px solid #ddd;
}

.canvas {
  flex: 1;
  width: 100%;
  height: 600px;
  border: 1px solid #ddd;
}

.properties-panel {
  position: absolute;
  top: 80px;
  right: 20px;
  width: 300px;
  padding: 15px;
  background: white;
  border: 1px solid #ddd;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
</style>
